import Vue from 'vue'
import Cookies from 'js-cookie'
import Element from 'element-ui'
import './assets/styles/element-variables.scss'

import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
import App from './App'
import store from './store'
import router from './router'
import directive from './directive' // directive
import plugins from './plugins' // plugins
import { download } from '@/utils/request'

import './assets/icons' // icon
import './permission' // permission control (路由权限文件，保持不变)
// 移除原来的 import permission from '@/permission'，因为要在当前文件直接注册指令

import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
// 分页组件
import Pagination from "@/components/Pagination";
// 自定义表格工具组件
import RightToolbar from "@/components/RightToolbar"
// 富文本组件
import Editor from "@/components/Editor"
// 文件上传组件
import FileUpload from "@/components/FileUpload"
// 图片上传组件
import ImageUpload from "@/components/ImageUpload"
// 图片预览组件
import ImagePreview from "@/components/ImagePreview"
// 字典标签组件
import DictTag from '@/components/DictTag'
// 头部标签组件
import VueMeta from 'vue-meta'
// 字典数据组件
import DictData from '@/components/DictData'
// 引入 echarts
import * as echarts from 'echarts'
// 将dataV自动注册所有组件为全局组件
import dataV from '@jiaminghi/data-view'

import '../src/views/assets/js/china.js'

// 全局方法挂载
Vue.prototype.getDicts = getDicts
Vue.prototype.getConfigKey = getConfigKey
Vue.prototype.parseTime = parseTime
Vue.prototype.resetForm = resetForm
Vue.prototype.addDateRange = addDateRange
Vue.prototype.selectDictLabel = selectDictLabel
Vue.prototype.selectDictLabels = selectDictLabels
Vue.prototype.download = download
Vue.prototype.handleTree = handleTree
// Vue 注册在原型上
Vue.prototype.$echarts = echarts

// ===================== 新增1：注册 v-hasPermi 指令（直接写在main.js中）=====================
Vue.directive('hasPermi', {
  inserted(el, binding, vnode) {
    // 从指令参数中获取需要的权限列表
    const requiredPerms = binding.value;
    // 从Vuex中获取当前用户已有的所有权限
    const userPerms = vnode.context.$store.getters && vnode.context.$store.getters.permissions;

    // 校验权限：如果需要权限且用户没有该权限，移除当前DOM元素（隐藏按钮/组件）
    if (requiredPerms && requiredPerms instanceof Array && requiredPerms.length > 0) {
      const hasPermission = requiredPerms.some(perm => userPerms.includes(perm));
      if (!hasPermission) {
        el.parentNode && el.parentNode.removeChild(el);
      }
    } else {
      throw new Error("使用 v-hasPermi 指令时，需传入权限数组，如 v-hasPermi=\"['xxx:xxx:xxx']\"");
    }
  }
});

// ===================== 新增2：挂载 $hasPermi 方法到Vue原型（供模板/方法中调用）=====================
Vue.prototype.$hasPermi = function(requiredPerms) {
  // 校验参数：必须是数组且非空
  if (!requiredPerms || !(requiredPerms instanceof Array) || requiredPerms.length === 0) {
    return false;
  }
  // 从Vuex获取用户已有的权限
  const userPerms = this.$store.getters && this.$store.getters.permissions;
  if (!userPerms || userPerms.length === 0) {
    return false;
  }
  // 判断用户是否拥有所需权限（只要有一个匹配即可）
  return requiredPerms.some(perm => userPerms.includes(perm));
};

// 全局组件挂载
Vue.component('DictTag', DictTag)
Vue.component('Pagination', Pagination)
Vue.component('RightToolbar', RightToolbar)
Vue.component('Editor', Editor)
Vue.component('FileUpload', FileUpload)
Vue.component('ImageUpload', ImageUpload)
Vue.component('ImagePreview', ImagePreview)

// 移除原来的 Vue.use(permission)，因为指令已直接注册
Vue.use(directive)
Vue.use(plugins)
Vue.use(VueMeta)

// 拖拽功能（保持不变）
Vue.directive('dialog-drag', {
  bind(el, binding, vnode) {
    const dialogHeader = el.querySelector('.el-dialog__header');
    const dragDom = el.querySelector('.el-dialog');

    // 初始样式
    dialogHeader.style.cursor = 'move';
    dragDom.style.position = 'absolute'; // 确保可以拖拽

    // 重置弹窗位置（强制居中）
    const resetPosition = () => {
      const screenWidth = document.body.clientWidth;
      const screenHeight = document.body.clientHeight;
      const dialogWidth = dragDom.offsetWidth;
      const dialogHeight = dragDom.offsetHeight;

      // 计算居中位置
      const left = (screenWidth - dialogWidth) / 2;
      const top = Math.max(0, (screenHeight - dialogHeight) / 2); // 避免负值

      dragDom.style.left = `${left}px`;
      dragDom.style.top = `${top}px`;

      // 存储初始居中位置（用于拖拽计算）
      dragDom.dataset.initialLeft = left;
      dragDom.dataset.initialTop = top;
    };

    // 监听弹窗打开事件
    const dialogComponent = vnode.componentInstance;
    dialogComponent.$watch('visible', (newVal) => {
      if (newVal) {
        Vue.nextTick(resetPosition); // DOM 渲染后重置位置
      }
    });

    // 拖拽逻辑（基于初始居中位置计算偏移量）
    dialogHeader.onmousedown = (e) => {
      e.preventDefault();

      // 获取初始居中位置
      const initialLeft = parseFloat(dragDom.dataset.initialLeft || 0);
      const initialTop = parseFloat(dragDom.dataset.initialTop || 0);

      // 鼠标按下时的偏移量（相对于弹窗左上角）
      const offsetX = e.clientX - initialLeft;
      const offsetY = e.clientY - initialTop;

      document.onmousemove = (e) => {
        // 计算新位置（基于鼠标当前位置 - 初始偏移量）
        let left = e.clientX - offsetX;
        let top = e.clientY - offsetY;

        // 边界检查（防止拖出屏幕）
        const maxLeft = document.body.clientWidth - dragDom.offsetWidth;
        const maxTop = document.body.clientHeight - dragDom.offsetHeight;

        left = Math.max(0, Math.min(left, maxLeft));
        top = Math.max(0, Math.min(top, maxTop));

        dragDom.style.left = `${left}px`;
        dragDom.style.top = `${top}px`;
      };

      document.onmouseup = () => {
        document.onmousemove = null;
        document.onmouseup = null;
      };
    };

    // 初始打开时居中
    if (dialogComponent.visible) {
      Vue.nextTick(resetPosition);
    }
  }
});

Vue.use(dataV)
DictData.install()

/**
 * If you don't want to use mock-server
 * you want to use MockJs for mock api
 * you can execute: mockXHR()
 *
 * Currently MockJs will be used in the production environment,
 * please remove it before going online! ! !
 */

Vue.use(Element, {
  size: Cookies.get('size') || 'medium' // set element-ui default size
})

Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})
